package com.dounine.clouddisk360.parser;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;

import com.dounine.clouddisk360.parser.deserializer.BaseConfig;
import com.dounine.clouddisk360.parser.deserializer.MsgConst;
import com.dounine.clouddisk360.store.CookieStoreUT;

public abstract class BaseParser<T extends BaseConfig> extends JSONBianary{

	protected CookieStoreUT cookieStoreUT = CookieStoreUT.getInstance();
	protected HttpClientContext httpClientContext = new HttpClientContext();
	protected HttpClient httpClient = HttpClients.createDefault();
	protected boolean requiredCookieStorePath = true;
	protected T config;
	
	public void initConfig(T config) {
		if (null == config) {
			throw MsgConst.CONFIG_COOKIESTORE_MSG;
		}
		this.config = config;
		if (requiredCookieStorePath) {
			if (StringUtils.isBlank(config.getBasePath())) {
				throw MsgConst.BASE_PATH_MSG;
			}
			cookieStoreUT.setBasePath(config.getBasePath());
		}
	}

	protected RequestConfig cookieRequestConfig() {
		RequestConfig config = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).build();
		return config;
	}
	
	protected RequestConfig cookieRequestConfig(String cookieSpecs) {
		RequestConfig config = RequestConfig.custom().setCookieSpec(cookieSpecs).build();
		return config;
	}

	/**
	 * 信任所有证书
	 * @return
	 */
	protected SSLContext sslAccessAll() {
		TrustStrategy trustStrategy = new TrustStrategy() {
			@Override
			public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
				return true;
			}
		};
		SSLContext sslContext = null;
		try {
			sslContext = new SSLContextBuilder().loadTrustMaterial(null, trustStrategy).build();
		} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
			e.printStackTrace();
		}
		return sslContext;
	}

	/**
	 * 获取磁盘上的cookie缓存
	 * 
	 * <pre>
	 * 	请注意,调用此方法,必须配置cookieStore保存目录
	 *  一般是配置BaseConfig的子类对象中的cookieStorePath属性
	 * </pre>
	 * 
	 * @return cookieStore仓库
	 */
	public CookieStore readCookieStoreDisk() {
		initCookieStorePath();
		httpClientContext.setCookieStore(cookieStoreUT.readCookieStoreForDisk());
		return httpClientContext.getCookieStore();
	}

	public CookieStore readCookieStoreDisk(String[] filterCookie) {
		initCookieStorePath();
		httpClientContext.setCookieStore(cookieStoreUT.readCookieStoreForDisk(filterCookie));
		return httpClientContext.getCookieStore();
	}

	private void initCookieStorePath() {
		cookieStoreUT.setBasePath(config.getBasePath());
	}

	public HttpClientContext getHttpClientContext() {
		return httpClientContext;
	}

	public void setHttpClientContext(HttpClientContext httpContext) {
		this.httpClientContext = httpContext;
	}

	public void setRequiredCookieStorePath(boolean requiredCookieStorePath) {
		this.requiredCookieStorePath = requiredCookieStorePath;
	}

	public CookieStoreUT getCookieStoreUT() {
		return cookieStoreUT;
	}

	public T getConfig() {
		return config;
	}

	
}
